#include "InterfazEncriptacion.h"
using namespace Interfaces;

InterfazEncriptacion::InterfazEncriptacion() {
	this->config = Configuracion::getInstancia();
	this->opcionElegida = -1;
	this->manejadorAdministrador = new ManejadorAdministrador();
	this->manejadorVotante = new ManejadorVotante();
	this->administradores = manejadorAdministrador->recuperarAdministradores();
	this->numeroAdministradorElegido = 0;
	;
}

void InterfazEncriptacion::mostrarMenuParaEncriptar() {

	string nombreDelAdministrador;
	while (this->opcionElegida != 3) {

		system("clear");
		cout << "Menu de Encriptación de Archivos" << endl << endl;
		cout << "Elija el archivo a encriptar: " << endl;
		cout << "      1- Archivo de Administradores" << endl;
		cout << "      2- Archivo de Votantes" << endl;
		cout << "      3- Volver" << endl;
		cout << endl;
		cout << "Elija la opcion: ";
		cin >> this->opcionElegida;
		cin.ignore(numeric_limits<streamsize>::max(), '\n');
		cout << endl;

		if (this->opcionElegida == 1 || this->opcionElegida == 2) {

			cout << "Seleccione al administrador al que le va a mandar el mensaje: " << endl;

			listarAdministradores(administradores);

			cout << endl << "Elija la opcion: ";
			cin >> this->numeroAdministradorElegido;
			cin.ignore(numeric_limits<streamsize>::max(), '\n');
			nombreDelAdministrador = administradores->at(this->numeroAdministradorElegido - 1)->getUsuario();
		}
		string pathDelArchivoAEncriptar = "";
		switch (this->opcionElegida) {
		case (1): {
			// encriptar el archivo administrador
			string path = this->config->getPathReportes() + "ListadoAdministradores.txt";
			RSA* rsa = new RSA();
			this->manejadorAdministrador->listarTodos();
			string pathArchivo = rsa->encriptarArchivo(nombreDelAdministrador, path, "Administradores");
			cout << "El archivo encriptado se encuentra en " + pathArchivo << endl;
			break;
		}
		case (2): {
			// encriptar el archivo de votantes
			string path = this->config->getPathReportes() + "ListadoVotantes.txt";
			RSA* rsa = new RSA();
			this->manejadorVotante->listarTodos();
			string pathArchivo = rsa->encriptarArchivo(nombreDelAdministrador, path, "Votantes");
			cout << "El archivo encriptado se encuentra en " + pathArchivo << endl;
			break;
		}
		case (3): {
			break;
		}
		default: {
			cout << "Opcion incorrecta. Por favor, vuelva a intentarlo" << endl;
			break;
		}
		}
		getchar();
	}

}

void InterfazEncriptacion::mostrarMenuParaDesencriptar(string admin) {

	int fin = 0;
	string directorio = this->config->getPathAdministradores() + admin + "/Mensajes/";

	vector<string>* archivos = Utils::getdir(directorio);

	while (fin != 1 && archivos != NULL) {

		system("clear");
		cout << "Menu de Desencriptacion de Archivos" << endl << endl;
		cout << "Elija el archivo a desencriptar: " << endl;

		for (unsigned int i = 0; i < archivos->size(); i++) {
			cout << "       " << i + 1 << "- " + archivos->at(i) << endl;
		}
		if (archivos->size() == 0) {
			cout << endl;
			cout << "No hay archivos para desencriptar" << endl;
			cout << "Presione enter para continuar.." << endl;
			cin.ignore(numeric_limits<streamsize>::max(), '\n');
			this->opcionElegida = -1;
			fin = 1;
		} else {
			cout << "       0- Volver" << endl;
			cout << endl;
			cout << "Elija la opcion: ";
			cin >> this->opcionElegida;
			cin.ignore(numeric_limits<streamsize>::max(), '\n');
		}

		if (this->opcionElegida <= archivos->size())
			fin = 1;
	}

	if (archivos == NULL) {
		cout << "Error : No existe el directorio del administrador. Presione Enter para volver";
		getchar();
	} else {
		if (this->opcionElegida != 0 && this->opcionElegida != -1) {
			// desencriptar el archivo elegido por el usuario
			RSA* rsa = new RSA();
			string pathArchivo = rsa->desencriptarArchivo(admin, archivos->at(this->opcionElegida - 1));
			delete rsa;
			cout << "El archivo desencriptado se encuentra en " + pathArchivo << endl;
			cout << "Presione una tecla para continuar..." << endl;
			getchar();
		}
	}
}

void InterfazEncriptacion::mostrarMenuParaRomperRSA() {

	system("clear");
	cout << "Ingrese el usuario administrador destinatario del mensaje atacado: " << endl;
	listarAdministradores(this->administradores);

	cout << endl << "Elija la opcion: ";
	cin >> this->numeroAdministradorElegido;
	cin.ignore(numeric_limits<streamsize>::max(), '\n');

	string nombreDelAdministrador = this->administradores->at(numeroAdministradorElegido - 1)->getUsuario();
	cout << endl;

	int opcionElegida = -1;
	int fin = 0;

	string directorio = this->config->getPathAdministradores() + nombreDelAdministrador + "/Mensajes/";

	vector<string>* archivos = Utils::getdir(directorio);

	while (fin != 1 && archivos != NULL) {

		system("clear");
		cout << "Menu de Ataque a RSA" << endl << endl;
		cout << "Elija el archivo a desencriptar por ataque: " << endl;

		for (unsigned int i = 0; i < archivos->size(); i++) {
			cout << "       " << i + 1 << "- " + archivos->at(i) << endl;
		}
		if (archivos->size() == 0) {
			cout << "       X- No hay archivos para desencriptar" << endl;
		}
		cout << "       0- Volver" << endl;
		cout << " Ingrese Opcion: ";
		cin >> opcionElegida;
		cin.ignore();
		cout << endl;

		if (opcionElegida <= archivos->size())
			fin = 1;
	}

	if (archivos == NULL) {
		cout << "Error : No existe el directorio del administrador. Presione Enter para volver";
		getchar();
		//		getchar();
	} else {
		if (opcionElegida != 0) {
			// desencriptar el archivo elegido por el usuario

			RomperRSA* romperRSA = new RomperRSA();
			ClaveRSA* clavePublica = new ClaveRSA(nombreDelAdministrador, Encriptacion::Publica);
			string pathArchivo = romperRSA->desencriptarMensaje(clavePublica, directorio + archivos->at(opcionElegida - 1), nombreDelAdministrador, archivos->at(opcionElegida - 1));
			delete romperRSA;

			cout << "El archivo desencriptado con el ataque se encuentra en " + pathArchivo << endl;
			cout << "Presione una tecla para continuar..." << endl;
			getchar();
			//			getchar();
		}
	}

}

void InterfazEncriptacion::listarAdministradores(vector<Administrador*>* administradores) {
	for (unsigned int i = 0; i < administradores->size(); i++) {
		cout << "      " << i + 1 << "- ";
		cout << administradores->at(i)->getUsuario() << endl;
	}
}

void InterfazEncriptacion::mostrarMenuEncriptarVigenere() {

	int opcionElegida = -1;
	int fin = 0;

	string directorio = this->config->getPathReportes();

	vector<string>* archivos = Utils::getdir(directorio);

	while (fin != 1 && archivos != NULL) {

		system("clear");
		cout << "Menu Encriptado Vigenere" << endl << endl;
		cout << "Elija el archivo a Encriptar: " << endl;
		cout << endl;
		cout << "NOTA: Los archivos deben encontrarse en " + directorio <<endl;
		for (unsigned int i = 0; i < archivos->size(); i++) {
			cout << "       " << i + 1 << "- " + archivos->at(i) << endl;
		}
		if (archivos->size() == 0) {
			cout << "       X- No hay archivos para encriptar" << endl;
		}
		cout << "       0- Volver" << endl;
		cout << " Ingrese Opcion: ";
		cin >> opcionElegida;
		cin.ignore();
		cout << endl;

		if (opcionElegida <= archivos->size())
			fin = 1;
	}

	if (archivos == NULL) {
		cout << "Error : No existe el directorio. Presione Enter para volver";
		getchar();
		//		getchar();
	} else {
		if (opcionElegida != 0) {
			// encriptar el archivo elegido por el usuario
			string claveParaEncriptar;
			cout << "Ingrese la clave para la Encriptacion: ";
			cin >> claveParaEncriptar;
			Vigenere* vigenere = new Vigenere(claveParaEncriptar);
			vigenere->generarArchivoEncriptado(directorio + archivos->at(opcionElegida - 1), 4);

			delete vigenere;

			cout << "El archivo encriptado se encuentra en " + config->getPathEncriptado() << endl;
			cout << "Presione una tecla para continuar..." << endl;
			getchar();
			getchar();
		}
	}

}

void InterfazEncriptacion::mostrarMenuDesencriptarVigenere() {

	int opcionElegida = -1;
	int fin = 0;

	string directorio = this->config->getPathEncriptado();

	vector<string>* archivos = Utils::getdir(directorio);

	while (fin != 1 && archivos != NULL) {

		system("clear");
		cout << "Menu Desencriptado Vigenere" << endl << endl;
		cout << "Elija el archivo a desencriptar: " << endl;
		cout << endl;
		cout << "NOTA: Los archivos deben encontrarse en " + directorio <<endl;
		for (unsigned int i = 0; i < archivos->size(); i++) {
			cout << "       " << i + 1 << "- " + archivos->at(i) << endl;
		}
		if (archivos->size() == 0) {
			cout << "       X- No hay archivos para desencriptar" << endl;
		}
		cout << "       0- Volver" << endl;
		cout << " Ingrese Opcion: ";
		cin >> opcionElegida;
		cin.ignore();
		cout << endl;

		if (opcionElegida <= archivos->size())
			fin = 1;
	}

	if (archivos == NULL) {
		cout << "Error : No existe el directorio. Presione Enter para volver";
		getchar();
		//		getchar();
	} else {
		if (opcionElegida != 0) {
			// desencriptar el archivo elegido por el usuario
			string claveParaEncriptar;
			cout << "Ingrese la clave para la Desencriptacion: ";
			cin >> claveParaEncriptar;
			Vigenere* vigenere = new Vigenere(claveParaEncriptar);
			vigenere->generarArchivoDesencriptado(directorio + archivos->at(opcionElegida - 1), 4);

			delete vigenere;

			cout << "El archivo desencriptado se encuentra en " + directorio << endl;
			cout << "Presione una tecla para continuar..." << endl;
			getchar();
			getchar();
		}
	}

}

InterfazEncriptacion::~InterfazEncriptacion() {
	delete manejadorAdministrador;
	delete manejadorVotante;
	for (unsigned int i = 0; i < administradores->size(); i++) {
		delete administradores->at(i);
	}
	delete administradores;
}
